#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "ual_types.h"
#include "port_conf.h"


#define dmsg_on 1

static int dmsg_flag = 0;

#if (dmsg_on)
#define dmsg(msg...)                                    \
	do                                                  \
	{                                                   \
		if(dmsg_flag)                                   \
		{                                                   \
			printf("[MSG]:%04d,%s:\t", __LINE__, __func__); \
			printf(msg);                                    \
		}                                                   \
	} while (0)
#else
#define dmsg(msg...)
#endif

#define derr_on 1
#if (derr_on)
#define derr(msg...)                                    \
	do                                                  \
	{                                                   \
		printf("[ERR]:%04d,%s:\t", __LINE__, __func__); \
		printf(msg);                                    \
	} while (0)
#else
#define derr(msg...)
#endif

FILE *fp;
char file_name_str[256];

/*定义开关类型： 0禁用开关， 1使能开关*/
#define onoff_type_off 0
#define onoff_type_on  1

/*定义开关列表长度*/
#define offen_node_list_length 20

/*定义可控开关总数*/
int     offen_node_total = 0;


typedef struct offen_node_t
{
	/*标记开关类型:0禁用开关，1使能开关*/
	int              offen_type;
	/*指向对应的ual节点*/
	ual_port_node   *ual_port_node_ptr;
}offen_node;

offen_node offen_node_list[offen_node_list_length];


/*查找开关节点，并收集到offen_node_list中*/
int find_offen_node(void)
{
	int ret = 0;
	/*搜索计数器，描述port_node在ual_port_node_list中的位置*/
	int idx = 0;
	/*记录port总数*/
	int ual_port_node_totoal = 0;
	/*记录已索索到的offen_node的个数*/
	int offen_node_count = 0;
	
	ual_port_node_totoal = (sizeof(ual_port_node_list)/sizeof(ual_port_node_list[0]));

	dmsg("get ual_port_node_total:%d\n", ual_port_node_totoal);

	for(idx = 0; idx < ual_port_node_totoal; idx++)
	{
		if(offen_node_count >= offen_node_list_length)
		{
			/*可控开关个数不能达到可控开关列表长度*/
			derr("没有更多节点存储开关，需要节点:%d, 限制节点:%d\n", (offen_node_count+1), offen_node_list_length);
		}
		if(NULL != strstr(ual_port_node_list[idx].name, "_off"))
		{
			/*若检测到禁用开关*/
			offen_node_list[offen_node_count].offen_type        = onoff_type_off;
			offen_node_list[offen_node_count].ual_port_node_ptr = &ual_port_node_list[idx];
			dmsg("get off node pos:%d, name:%s\n",
					offen_node_count, 
					offen_node_list[offen_node_count].ual_port_node_ptr->name);
			offen_node_count++;
		}
		else if(NULL != strstr(ual_port_node_list[idx].name, "_on"))
		{
			/*若检测到使能开关*/
			offen_node_list[offen_node_count].offen_type = onoff_type_on;
			offen_node_list[offen_node_count].ual_port_node_ptr = &ual_port_node_list[idx];
			dmsg("get en  node pos:%d, name:%s\n",
					offen_node_count, 
					offen_node_list[offen_node_count].ual_port_node_ptr->name);
			offen_node_count++;
		}
	}
	offen_node_total = offen_node_count;
	dmsg("get offen node tootal:%d\n", offen_node_total);
	return 0;
}

void show_usage(char *exe_name)
{
	int pos = 0;
	printf("使用说明:\n");
    printf("该程序用于操作禁用使能开关, 列表如下:\n");
    printf("\t编 号 \t名 称\n");
	for(pos=0; pos < offen_node_total; pos++)
	{
		printf("  \t%d   \t%s\n", pos,
					offen_node_list[pos].ual_port_node_ptr->name);
	}
    printf("使用方法:\n");
	printf("%s 编号[0~%d]  开关[0/1] 调试[0/1]\n", exe_name, offen_node_total-1);
}

int ctrl_offen(int pos, int val)
{
	memset(file_name_str,0,256);
	sprintf(file_name_str,"/ual/%s/value",offen_node_list[pos].ual_port_node_ptr->name);
	if ((fp = fopen(file_name_str, "rb+")) == NULL)
	{
		printf("Cannot open %s.\n",file_name_str);
		return -1;
	}
	fprintf(fp, "%d", val);

	fclose(fp);

	return 0;
}

int main(int argc, char **argv)
{
	int offen_pos = -1;
	int offen_val = 0;

	if(argc == 4)
	{
		dmsg_flag = atoi(argv[3]);
		if(dmsg_flag != 1)
		{
			dmsg_flag = 0;
		}else
		{
			dmsg_flag = 1;
		}
	}

	find_offen_node();

	if(argc != 4 && argc != 3)
	{
		show_usage(argv[0]);
		return -1;
	}

	if(0 == strcmp(argv[1], "0"))
	{
		offen_pos = 0;
	}else
	{
		offen_pos = atoi(argv[1]);
		if(offen_pos <= 0 || offen_pos > (offen_node_total-1))
		{
			/*offen_pos <=0 是为了防止atoi失败返回0误判为0索引*/
			show_usage(argv[0]);
			return -1;
		}
	}

	offen_val = atoi(argv[2]);
	if(offen_val != 1)
	{
		offen_val = 0;
	}else
	{
		offen_val = 1;
	}
	if(0 != ctrl_offen(offen_pos, offen_val))
	{
		printf("执行失败:[ERROR]\n");
	}
	printf("执行完毕:[END]\n");
	return 0;
}
